package lib

import (
	"ManageServer/utils/gls"
	"ManageServer/utils/logger"
	"fmt"
	"github.com/chenhg5/collection"
	"github.com/gin-gonic/gin"
	"strings"
)

var RouteAuth = map[string]map[string][]string{}

func Recovery() gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				logger.PanicLogger.Error(fmt.Errorf("%s", err).Error())
			}
		}()
		c.Next()
	}
}

func SetCacheControl() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Header("Cache-Control", "private, max-age=86400")
	}
}

func CleanGls() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 调用处理过程
		c.Next()
		// 用于释放当前 Goroutine 对应的map资源
		gls.Clean()
	}
}

func IsRouteIgnore(c *gin.Context, middleware string) bool {
	var fullPath = c.FullPath()

	if middleware == "session" {
		var ignore = []string{"/v1.0/api/user/WebLogin", "/v1.0/api/user/Sync", "/v1.0/api/config/Get", "/v1.0/api/user/GetDepartment", "/v1.0/api/user/H5Login", "/v1.0/api/user/H5Register", "/v1.0/api/captcha/get"}
		return collection.Collect(ignore).Contains(fullPath)
	}

	if middleware == "auth" {
		var ignore = []string{"/v1.0/api/user/WebLogin", "/v1.0/api/user/H5Register", "/v1.0/api/config/Get", "/v1.0/api/user/GetDepartment", "/v1.0/api/user/Update", "/v1.0/api/user/Create", "/v1.0/api/user/AccompanyList", "/v1.0/api/accompanyRecord/Get", "/v1.0/api/staffRecord/Get", "/v1.0/api/user/H5Login", "/v1.0/api/accompanyRecord/Create", "/v1.0/api/user/Registe", "/v1.0/api/user/GetDepartment", "/v1.0/api/staffRecord/Create", "/v1.0/api/user/Sync", "/v1.0/api/captcha/get"}
		return collection.Collect(ignore).Contains(fullPath)
	}
	return false
}

func SetRouteAuthorization(route_auth map[string]map[string][]string) {
	// 注册路由时同时注册路由权限
	for role, role_auth := range route_auth {
		if RouteAuth[role] == nil {
			RouteAuth[role] = make(map[string][]string, 0)
		}
		// 管理员,职工,访客
		for module, module_auth := range role_auth {
			// 模块
			RouteAuth[role][module] = module_auth
		}

	}
}

func RouteAuthorization() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 登录不进行 权限 验证
		if IsRouteIgnore(c, "auth") {
			c.Next()
			return
		}

		var module, function string
		// 获取当前模块、方法
		fullPath := c.FullPath()
		fullPathAttr := strings.Split(fullPath, "/")
		if len(fullPathAttr) < 5 {
			// 路由规则非 /v1.0/api/[module]/[function] 时，不校验路由
			c.Next()
			return
		}
		module = fullPathAttr[3]
		function = fullPathAttr[4]
		// 获取当前角色
		var current_role string

		inter_role, exist := c.Get("role")
		if !exist {
			c.JSON(200, gin.H{
				"code": "401",
				"msg":  "获取当前角色失败",
				"data": map[string]interface{}{},
			})
			c.Abort()
			return
		}
		current_role = inter_role.(string)

		//获取当前角色路由-模块权限
		modules := RouteAuth[current_role]

		//获取当前角色路由-方法权限
		functions := modules[module]

		//判断当前路由是否有权限
		if !collection.Collect(functions).Contains(function) {
			c.JSON(200, gin.H{
				"code": "0004",
				"msg":  "无此功能权限",
				"data": map[string]interface{}{},
			})
			c.Abort()
			return
		}

		c.Next()
	}
}
